/**
 * Created by meiguizhinian on 2018/7/6
 * Copyright © 2018 lixiaolong. All rights reserved.
 */

//单例/全静态/枚举
ivy.MultiLanguageManager = {
	getInstance: function () {
		return this;
	},

	initWithFile : function(path) {
		let is = new ivy.InputStream(path);
		if (is.empty()) {
			return;
		}
		let kvConfigCount = is.readJInt16();
		for (let i = 0; i < kvConfigCount; ++i) {
			let keyV = is.readStringUTF8();
			this._kvMap[keyV] = is.readStringUTF8();
		}

		let fontConfigCount = is.readJInt16();
		for (let i = 0; i < fontConfigCount; ++i) {
			let key = is.readStringUTF8();
			let tempVec = [];
			let count = is.readJInt16();
			for (let j = 0; j < count; ++j) {
				let valueV = is.readStringUTF8();
				tempVec.push(valueV);
			}
			this._fontConfigMap.set(key, tempVec);
		}

		this._languageCount = is.readJInt16();

		let curTag = is.readStringUTF8();
		this._curLanguageTag = curTag;
		this._preLanguageTag = curTag;
		this._defaultLanguageTag = curTag;
		this._curLanguageIndex = 0;
		this._languageTagFindByStrMap.set(curTag, 0);
		this._languageTagFindByIndexMap[0] = curTag;
		for (let i = 0; i < this._languageCount - 1; ++i) {
			let tag = is.readStringUTF8();
			this._languageTagFindByStrMap.set(tag, i+1);
			this._languageTagFindByIndexMap[i+1] = tag;
		}
		//srcLanguageDataMap_
		let gameDataLMap = new LLDictionary();//std::map<std::string, int32_t>
		let gameDataCount = is.readJInt32();
		for (let i = 0; i < gameDataCount; ++i) {
			let str = is.readStringUTF8();
			gameDataLMap.set(str, is.readJInt32());
		}
		this._srcLanguageDataMap.set(ivy.MultiLanguageManager.InterpretDataType.IDT_GameData, gameDataLMap);

		let uiDataLMap = new LLDictionary();//std::map<std::string, int32_t>
		let uiDataCount = is.readJInt32();
		for (let i = 0; i < uiDataCount; ++i) {
			let str = is.readStringUTF8();
			uiDataLMap.set(str, is.readJInt32());
		}
		this._srcLanguageDataMap.set(ivy.MultiLanguageManager.InterpretDataType.IDT_UIData, uiDataLMap);

		let scriptDataLMap = new LLDictionary();//std::map<std::string, int32_t>
		let scriptDataCount = is.readJInt32();
		for (let i = 0; i < scriptDataCount; ++i) {
			let str = is.readStringUTF8();
			scriptDataLMap.set(str, is.readJInt32());
		}
		this._srcLanguageDataMap.set(ivy.MultiLanguageManager.InterpretDataType.IDT_ScriptData, scriptDataLMap);

		let teachDataLMap = new LLDictionary();//std::map<std::string, int32_t>
		let teachDataCount = is.readJInt32();
		for (let i = 0; i < teachDataCount; ++i) {
			let str = is.readStringUTF8();
			teachDataLMap.set(str, is.readJInt32());
		}
		this._srcLanguageDataMap.set(ivy.MultiLanguageManager.InterpretDataType.IDT_TeachData, teachDataLMap);
	},
	changeLanguageByTag : function(tag) {
		if (this.isLanguageExist(tag)) {
			this._initAnotherLanguageDataWithTag(tag);
			this._curLanguageTag = tag;
			this._curLanguageIndex = this._languageTagFindByStrMap.get(tag);

			for (let fun of this._staticRefreshFunctionVec) {
				fun();
			}
			for (let [first, second] of this._dynamicRefreshFunctionMap) {
				second(first);
			}
			this._preLanguageTag = this._curLanguageTag;
		}
	},
	getCurrentLanguageIndex : function() {
		let tag = this.getCurrentLanguageTag();
		return this._languageTagFindByStrMap.get(tag) || -1;
	},
	getExistLanguageTag : function() {
		return this._languageTagFindByStrMap.allKeys();
	},
	getExistLanguageIndexMap : function() {
		return this._languageTagFindByIndexMap;
	},
	getCurrentLanguageTag : function() {
		return this._curLanguageTag;
	},
	isLanguageExist : function(tag) {
		return this._languageTagFindByStrMap.has(tag);
	},
	getString : function(s, type, serchAllIfNotFind) {
		if (this._curLanguageIndex === 0) {
			return s;
		} else {
			if (this._srcLanguageDataMap.get(type).has(s)) {
				let findIndex = this._srcLanguageDataMap.get(type).get(s);
				if (this._curSwitchLanguageDataMap.get(type).has(findIndex)) {
					return this._curSwitchLanguageDataMap.get(type).get(findIndex);
				}
			}
			if (serchAllIfNotFind) {
				for (let checkType= ivy.MultiLanguageManager.InterpretDataType.IDT_GameData; checkType<=ivy.MultiLanguageManager.InterpretDataType.IDT_TeachData; ++checkType) {
					if (checkType === type) {
						continue;
					}
					if (this._srcLanguageDataMap.get(checkType).has(s)) {
						let findIndex = this._srcLanguageDataMap.get(checkType).get(s);
						if (this._curSwitchLanguageDataMap.get(checkType).has(findIndex)) {
							return this._curSwitchLanguageDataMap.get(checkType).get(findIndex);
						}
					}
				}
			}
			return s;
		}
	},
	getStringBySaveMoment : function(s, type, serchAllIfNotFind) {
		if (this._curLanguageIndex === 0 && this._preLanguageTag === this._curLanguageTag) {
			return s;
		} else {
			if ((this._preLanguageTag !== this._curLanguageTag) && (this._languageTagFindByStrMap.get(this._preLanguageTag) !== 0)) {

			} else if (this._srcLanguageDataMap.get(type).has(s)) {
				let findIndex = this._srcLanguageDataMap.get(type).get(s);
				if (this._curSwitchLanguageDataMap.get(type).has(findIndex)) {
					return this._curSwitchLanguageDataMap.get(type).get(findIndex);
				}
			}
			if (serchAllIfNotFind) {
				for (let checkType = ivy.MultiLanguageManager.InterpretDataType.IDT_GameData; checkType <= ivy.MultiLanguageManager.InterpretDataType.IDT_TeachData; ++checkType) {
					if (checkType === type)
						continue;
					if (this._srcLanguageDataMap.get(checkType).has(s)) {
						let findIndex = this._srcLanguageDataMap.get(checkType).get(s);
						if (this._curSwitchLanguageDataMap.get(checkType).has(findIndex)) {
							return this._curSwitchLanguageDataMap.get(checkType).get(findIndex);
						}
					}
				}
			}
			return s;
		}
	},
	registerStaticRefreshFunction : function(rf) {
		this._staticRefreshFunctionVec.push(rf);
	},
	registerDynamicRefreshFunction : function(sender, rf) {
		this._dynamicRefreshFunctionMap.set(sender, rf);
	},

	unregisterDynamicRefreshFunction : function(sender) {
		return this._dynamicRefreshFunctionMap.erase(sender);
	},
	isStringExists : function(text) {
		for (let checkType = ivy.MultiLanguageManager.InterpretDataType.IDT_GameData; checkType <= ivy.MultiLanguageManager.InterpretDataType.IDT_TeachData; ++checkType) {
			if (this._srcLanguageDataMap.get(checkType).has(text)) {
				let findIndex = this._srcLanguageDataMap.get(checkType).get(text);
				if (this._curSwitchLanguageDataMap.get(checkType).has(findIndex)) {
					return true;
				}
			}
		}
		return false;
	},

	getDefautLanguageTag : function() {
		return this._defaultLanguageTag;
	},
	getCurrentLanguageFontPath : function(path) {
		let vec = this._fontConfigMap.get(this._defaultLanguageTag);
		if (vec!==undefined) {
			let index = 0;
			for (let i=0; i!==vec.length; ++i) {
				if (vec[i] === path) {
					break;
				}
				++index;
			}
			let second = this._fontConfigMap.get(this._curLanguageTag);
			if (second!==undefined) {
				if (index < second.length) {
					if (second[index].length > 0) {
						return second[index];
					}
				}
			}
		}
		return path;
	},
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////private:
	_initAnotherLanguageDataWithTag : function(tag) {
		if (this._languageTagFindByStrMap.has(tag)) {
			let is = new ivy.InputStream("i18n/" + tag + "/data.bin");
			if (is.empty()) {
				return;
			}

			let gameDataLMap = new LLDictionary();//std::map<int32_t, std::string>
			let gameDataCount = is.readJInt32();
			this._curSwitchLanguageDataMap.clear();
			for (let i = 0; i < gameDataCount; ++i) {
				let index = is.readJInt32();
				gameDataLMap.set(index, is.readStringUTF8());
			}
			this._curSwitchLanguageDataMap.set(ivy.MultiLanguageManager.InterpretDataType.IDT_GameData, gameDataLMap);

			let uiDataLMap = new LLDictionary();//std::map<int32_t, std::string>
			let uiDataCount = is.readJInt32();
			for (let i = 0; i < uiDataCount; ++i) {
				let index = is.readJInt32();
				uiDataLMap.set(index, is.readStringUTF8());
			}
			this._curSwitchLanguageDataMap.set(ivy.MultiLanguageManager.InterpretDataType.IDT_UIData, uiDataLMap);

			let scriptDataLMap = new LLDictionary();//std::map<int32_t, std::string>
			let scriptDataCount = is.readJInt32();
			for (let i = 0; i < scriptDataCount; ++i) {
				let index = is.readJInt32();
				scriptDataLMap.set(index, is.readStringUTF8());
			}
			this._curSwitchLanguageDataMap.set(ivy.MultiLanguageManager.InterpretDataType.IDT_ScriptData, scriptDataLMap);

			let teachDataLMap = new LLDictionary();//std::map<int32_t, std::string>
			let teachDataCount = is.readJInt32();
			for (let i = 0; i < teachDataCount; ++i) {
				let index = is.readJInt32();
				teachDataLMap.set(index, is.readStringUTF8());
			}
			this._curSwitchLanguageDataMap.set(ivy.MultiLanguageManager.InterpretDataType.IDT_TeachData, teachDataLMap);
		}
	},
	_curLanguageTag: "",
	_preLanguageTag : "",
	_defaultLanguageTag : "",
	_curLanguageIndex : 0,
	_languageCount : 0,
	_languageTagFindByStrMap : new LLDictionary(),
	_languageTagFindByIndexMap : {},
	_srcLanguageDataMap : new LLDictionary(),
	_curSwitchLanguageDataMap : new LLDictionary(),
	_kvMap : {},
	_fontConfigMap : new LLDictionary(),

	_staticRefreshFunctionVec : [],
	_dynamicRefreshFunctionMap : new LLDictionary(),
};

ivy.MultiLanguageManager.InterpretDataType = {
	IDT_GameData    : 0,
	IDT_UIData      : 1,
	IDT_ScriptData  : 2,
	IDT_TeachData   : 3,
};